package vertx;

import io.vertx.config.ConfigRetriever;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.mysqlclient.MySQLConnectOptions;
import io.vertx.mysqlclient.MySQLPool;
import io.vertx.sqlclient.*;

import java.util.ArrayList;
import java.util.List;

public class FuturePromiseVerticle extends AbstractVerticle {
  //第一步 声明路由
  Router router;
  //第一配置连接参数
  MySQLConnectOptions connectOptions;
  //第二个配置连接池 Pool Options
  PoolOptions poolOptions=new PoolOptions()
    .setMaxSize(5);
  //第三个 Create the chlient pool
  MySQLPool clint;
  @Override
  public void start(Promise<Void> startPromise) throws Exception {

    //第一步 文件管理 相当问yml
    ConfigRetriever retriever=ConfigRetriever.create(vertx);
    retriever.getConfig(ar ->{
      if(ar.failed()){

      } else {
        JsonObject config=ar.result();


        connectOptions =new MySQLConnectOptions()
          .setPort(Integer.parseInt(config.getValue("port").toString()))
          .setHost(config.getString("host"))
          .setDatabase(config.getString("database"))
          .setUser(config.getString("user"))
          .setPassword(config.getString("password"));
        clint= MySQLPool.pool(vertx,connectOptions, poolOptions);
        //第二部 初始化router
        router =Router.router(vertx);
        //第三步 将Router与vertx HttpServer 绑定

        //第四步配置解析Url 改成get 只能接受get请求
        router.get("/").handler(
          req -> {
            req.response()
              //text/plain修改json格式application/json
              .putHeader("content-type", "application/json")
              .end("Hello from Vert.x!");
          });
        //数据库访问
        router.get("/test/list").handler(
          req -> {
            Integer page=Integer.valueOf(req.request().getParam("page"));

            clint.getConnection(arl->{
              if(arl.succeeded()){
                System.out.println("Connected");
                //Obtain our connection
                SqlConnection conn=arl.result();
                Integer offset=(page-1)*10;
                //第二部，用获取到的连接查询数据库
                this.getCon()
                  .compose(con -> this.getRows(con,offset))
                  .onSuccess(rows -> {

                  });
                conn.preparedQuery("select id from user limit 10 offset ?")
                  .execute(Tuple.of(offset), ar2->{
                    if(ar2.succeeded()){
                      //第三步加功查询出来的数据并返回给客户端
                      List list=new ArrayList<JsonObject>();
                      ar2.result().forEach(item->{
                        JsonObject entries = new JsonObject();
                        entries.put("id",entries.getValue("id"));
                        list.add(entries);
                      });
                      req.response()
                        //text/plain修改json格式application/json
                        .putHeader("content-type", "application/json")
                        .putHeader("charset","utf-8")
                        .end(list.toString());
                      conn.close();
                    }else {
                      req.response()
                        //text/plain修改json格式application/json
                        .putHeader("content-type", "application/json")
                        .putHeader("charset","utf-8")
                        .end(ar2.cause().toString());
                    }
                  });
              }else {
                System.out.println("Could not connect:"+arl.cause().getMessage());
              }
            });
          });
        vertx.createHttpServer().requestHandler(router).listen(8888,http->{
          if (http.succeeded()) {
            startPromise.complete();
            System.out.println("HTTP server started on port 8888");
          } else {
            startPromise.fail(http.cause());
          }
        });
      }
    });


  }
  //第一步获取数据库连接
  private Future<SqlConnection> getCon(){
    //泛型必须一样
    Promise<SqlConnection> promise=Promise.promise();
    clint.getConnection(arl -> {
      if(arl.succeeded()) {
        System.out.println("Connected");
        //Obtain our connection
        SqlConnection conn = arl.result();

        //这一点非常关键 这个写法是固定写法
        promise.complete(conn);
      } else {
        promise.fail(arl.cause());
      }
    });
       //这一点非常关键 这个写法是固定写法
      return promise.future();
  }
     //第二部，用获取的连接查询数据库
  private Future<RowSet<Row>> getRows(SqlConnection conn,Integer offset){
    Promise<RowSet<Row>> promise=Promise.promise();
    conn.preparedQuery("select id from user limit 10 offset ?")
      .execute(Tuple.of(offset), ar2->{
        if(ar2.succeeded()){
        promise.complete(ar2.result());
        } else {
          promise.fail(ar2.cause());
        }
        });
    return promise.future();
  }
}
